Raspberry PiとAWSを繋いでみる ~AWS IoT Device Clientの導入~
こんにちは。CX事業本部のKyoです。前回に続いてラズパイとAWS IoT Coreを触っていきます。
前回はこちら。
概要
前回セットアップしたラズパイにAWS IoT Device Clientを導入して、MQTTでIoT Coreとの疎通確認をします。具体的には以下の手順を行います。
AWS IoT Device Client のインストールと設定
ステップ 1: AWS IoT Device Client をダウンロードして保存する
まずはAWS IoT Device Client のダウンロード、コンパイル、ラズパイへのインストールを行います。
そもそもAWS IoT Device Clientとは?という情報はダウンロード元リポジトリのREADMEにあるので待ち時間に覗いてみるといいと思います(ダウンロード、ビルドを合わせると20分くらいでした)。
ここでもざっくり概要をまとめてみます。
- IoTデバイスとAWS IoTサービスと連携するためのリファレンス実装 (C++製)
- 運用のベストプラクティスが組み込まれている
- OSSなのでPoCに使ったり、改修してもよい
- デフォルトで以下のAWSサービスにアクセスできる
- AWS IoT Core
- AWS IoT Device Management
- AWS IoT Device Defender
ビルドが終わったら以下のコマンドで確認します。
$ ./aws-iot-device-client --help AWS IoT Device Client BINARY For more documentation, see https://github.com/awslabs/aws-iot-device-client Available sub-commands: --help: Get more help on commands --version: Output current version --export-default-settings <JSON-File-Location>: Export default settings for the AWS IoT Device Client binary to the specified file and exit program ...
この後に使用するディレクトリを作成し、パーミッションを変更してこのステップは完了です。
ステップ 2: AWS IoT で Raspberry Pi をプロビジョニングする
このステップは「デバイス証明書ファイルを作成およびダウンロードする」と「AWS IoTリソースの作成」の2つから成ります。
デバイス証明書ファイルを作成およびダウンロードする
ラズパイにSSHして、作業を行います。
create-keys-and-certificate
でAWS IoTに証明書を作り、出力された情報をラズパイ側にファイルとして保存します。
aws iot create-keys-and-certificate \ --set-as-active \ --certificate-pem-outfile "~/certs/testconn/device.pem.crt" \ --public-key-outfile "~/certs/testconn/public.pem.key" \ --private-key-outfile "~/certs/testconn/private.pem.key"
…こんなエラーが出ました。
An error occurred (AccessDeniedException) when calling the CreateKeysAndCertificate operation: User: is not authorized to perform: iot:CreateKeysAndCertificate on resource: * because no identity-based policy allows the iot:CreateKeysAndCertificate action
ポリシーが足りないと言われているので、ラズパイのAWS CLIに設定しているIAMユーザーのポリシーを以下の形に変更しました。具体的には前回作成したポリシーにiot:CreateKeysAndCertificate
を追加しています。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iot:DescribeEndpoint", "iot:CreateKeysAndCertificate" ], "Resource": "*" } ] }
改めてコマンドを実行すると、証明書ファイルを作成できました。レスポンスに含まれるcertificateArn
は後で必要になるのでメモしておきます。また、証明書ディレクトリとそのファイルに対するアクセス許可を設定しておきます。
以上でデバイス証明書ファイルがラズパイにインストールできました。
AWS IoT リソースの作成
ローカルPCのAWS CLIから作業を行います。今回はAdmin権限を持つユーザーを利用しました。
- デバイスデータエンドポイントのアドレスを取得 (後で使うのでメモしておきます)
aws iot describe-endpoint --endpoint-type IoT:Data-ATS
- AWS IoT のモノを作成
aws iot create-thing --thing-name "DevCliTestThing"
- AWS IoT ポリシーを作成
aws iot create-policy \ --policy-name "DevCliTestThingPolicy" \ --policy-document "file://~/policies/dev_cli_test_thing_policy.json"
ポリシーの定義ファイルであるdev_cli_test_thing_policy.json
の中身は以下のようになっています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Subscribe", "iot:Receive", "iot:Connect" ], "Resource": [ "*" ] } ] }
- ポリシーをデバイス証明書にアタッチ
aws iot attach-policy \ --policy-name "DevCliTestThingPolicy" \ --target ""
- デバイス証明書を AWS IoT のモノのリソースにアタッチ
aws iot attach-thing-principal \ --thing-name "DevCliTestThing" \ --principal ""
特にハマりどころはなかったですが、モノ、ポリシー、デバイス証明書の関係性を把握できると理解が深まりそうです。
ステップ 3: AWS IoT Device Client を設定して接続をテストする
ラズパイ側で、AWS IoT Device Clientの設定ファイルを作成します。デバイスデータエンドポイントを前のステップで取得したものに置き換えるのを忘れないようにします。
設定を理解する上では以下が参考になりそうです。
AWSマネジメントコンソールからMQTT テストクライアントを開き、MQTTメッセージをサブスクライブする準備をします。
※ トピックフィルターに設定した#
はワイルドカードです。
ラズパイ側からAWS IoT Device Clientを実行します。
./aws-iot-device-client --config-file ~/dc-configs/dc-testconn-config.json
しかし、以下のようなエラーが発生しました。
2023-03-24T10:57:55.197Z [INFO] {Main.cpp}: Now running AWS IoT Device Client version v1.8.18-6633b39 2023-03-24T10:57:55.214Z [ERROR] {FileUtils.cpp}: Failed to create directory /var/log/aws-iot-device-client/ 2023-03-24T10:57:55.215Z [ERROR] {Main.cpp}: *** AWS IOT DEVICE CLIENT FATAL ERROR: Failed to initialize AWS CRT SDK. AWS IoT Device Client must abort execution, reason: Failed to initialize AWS CRT SDK Please check the AWS IoT Device Client logs for more information Segmentation fault
ディレクトリの作成に失敗しているようです。エラーメッセージを元に対策を見つけました。
上記に従ってディレクトリの作成とパーミッションの変更を行い、改めてコマンドを実行します。
無事にエラーが消え、
2023-03-24T11:18:05.299Z [INFO] {Main.cpp}: Now running AWS IoT Device Client version v1.8.18-6633b39 2023-03-24T11:18:05.311Z [INFO] {SharedCrtResourceManager.cpp}: SDK logging is enabled. Check /var/log/aws-iot-device-client/sdk.log for SDK logs. 2023-03-24T11:18:05.313Z [DEBUG] {LockFile.cpp}: creating lockfile 2023-03-24T11:18:05.314Z [DEBUG] {Retry.cpp}: Retryable function starting, it will retry until success 2023-03-24T11:18:05.391Z [INFO] {SharedCrtResourceManager.cpp}: Establishing MQTT connection with client id DevCliTestThing... 2023-03-24T11:18:05.641Z [INFO] {SharedCrtResourceManager.cpp}: MQTT connection established with return code: 0 2023-03-24T11:18:05.641Z [INFO] {SharedCrtResourceManager.cpp}: Shared MQTT connection is ready! 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Provisioning with Secure Elements is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Config shadow is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Jobs is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Secure Tunneling is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Device Defender is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: Sample shadow is disabled 2023-03-24T11:18:05.642Z [INFO] {Main.cpp}: PubSub is enabled 2023-03-24T11:18:05.642Z [INFO] {samples/PubSubFeature.cpp}: Creating Pub/Sub file: /home/pi/.aws-iot-device-client/pubsub/publish-file.txt 2023-03-24T11:18:05.642Z [INFO] {FileUtils.cpp}: Successfully create directory /home/pi/.aws-iot-device-client/pubsub/ with required permissions 745 2023-03-24T11:18:05.642Z [INFO] {samples/PubSubFeature.cpp}: Creating Pub/Sub file: /home/pi/.aws-iot-device-client/pubsub/subscribe-file.txt 2023-03-24T11:18:05.643Z [INFO] {Main.cpp}: Sensor Publish is disabled 2023-03-24T11:18:05.643Z [INFO] {SharedCrtResourceManager.cpp}: Starting Device Client features. 2023-03-24T11:18:05.643Z [DEBUG] {FeatureRegistry.cpp}: Attempting to start Pub Sub Sample 2023-03-24T11:18:05.643Z [INFO] {samples/PubSubFeature.cpp}: Starting Pub Sub Sample 2023-03-24T11:18:05.643Z [INFO] {Main.cpp}: Client base has been notified that Pub Sub Sample has started 2023-03-24T11:18:05.697Z [DEBUG] {samples/PubSubFeature.cpp}: PublishCompAck: PacketId:(Pub Sub Sample), ErrorCode:0 2023-03-24T11:18:05.705Z [DEBUG] {samples/PubSubFeature.cpp}: SubAck: PacketId:(Pub Sub Sample), ErrorCode:0
テストクライアントにも通知が届いていました!
おわりに
今回はAWS IoT Device Clientの導入とAWS IoT Coreへの疎通確認を行いました。
前回がAWS CLIを使った疎通だったのに対して、今回はAWS IoT Device ClientからのMQTTによる疎通です。デバイス証明書の設定など、ぐっとIoTっぽくなりましたね。
また今回はほぼ全工程をAWS CLIから設定を行いました。CLIから行うことでどのAWS APIを叩いているのか、必要な権限は何かが、理解しやすくてよかったです。